package rwt.server.mtl.ada;

import java.io.IOException;
import java.util.Map;

import org.slf4j.*;

import rwt.msg.AdaNativeMessageConverter;
import rwt.server.core.BaseMessage;
import rwt.server.mtl.*;
import rwt.server.mtl.java.MethodDictionary;

public class AdaMessageAdaptor implements IMessageAdaptor
{
	private static final Logger logger = LoggerFactory.getLogger(AdaMessageAdaptor.class);

	private Map<Integer, Class<? extends BaseMessage>> idToClassMap;
	private MethodDictionary methods = new MethodDictionary();
	private JsonConverter jsonConverter;
	private AdaNativeMessageConverter adaNativeConverter;

	/**
	 * Constructs a new message adaptor.
	 */
	public AdaMessageAdaptor(Map<Integer, Class<? extends BaseMessage>> idToClassMap)
	{
		try
		{
			this.adaNativeConverter = new AdaNativeMessageConverter();
		}
		catch (Exception e)
		{
			logger.error("Could not load Ada-native message translator! Please ensure GNAT 2011 and AJIS 2011 are " + 
					"proprerly installed on your system.", e);
			return;
		}
		this.adaNativeConverter.setAnnotations(
				SplitMethodOnlyField.class,
				MakeMethodOnlyField.class,
				SplitMethodOnlyMessage.class,
				MakeMethodOnlyMessage.class);
		
		this.idToClassMap = idToClassMap;
		this.jsonConverter = new JsonConverter(idToClassMap);
	}
	
	public byte[] messageToBytes(BaseMessage message) throws IOException, IllegalAccessException
	{
		return adaNativeConverter.toBytes(message);
	}
	
	public BaseMessage bytesToMessage(byte[] bytes) throws IOException
	{
		int opCode = (int) bytes[0] & 0xff;
		if (opCode == 0)
		{
			// Extended message
			opCode = (int) bytes[1] & 0xff;
		}
		Class<? extends BaseMessage> messageClass = idToClassMap.get(opCode);
		return adaNativeConverter.fromBytes(bytes, messageClass);
	}
	
	public BaseMessage jsonToMessage(String json) throws IOException
	{
		return jsonConverter.fromJson(json);
	}

	public String messageToJson(BaseMessage message) throws IOException
	{
		return jsonConverter.toJson(message);
	}
}
